// -*- coding: utf-8 -*-
package com.chensq.devops
import groovy.json.JsonOutput
import java.util.regex.Matcher
import java.util.regex.Pattern


//将两个不同的 git 拉取操作放入到并行的任务中，你可以将每个 git 拉取操作封装到一个 Groovy 的闭包（Closure）中，然后使用 Jenkins 的 parallel 方法

def pullCode(String branch, String credentialsId) {
    this.msg = new BuildMessage()
    def isSuccess = false
    def errMsg = ""
    def tasks = [:]

    tasks["Pulling Code by Jenkins"] = {
        try {
            git(
                changelog: true,
                poll: true,
                url: env.GIT_URL,  // 使用 env.GIT_URL 获取 Jenkins Git 地址
                branch: params.BRANCH,
                credentialsId: credentialsId
            )
            env.TAG = sh(
                returnStdout: true,
                script: "git log -n 1 --pretty=format:'%h'"
            ).trim()

            env.commitMessage = sh(
                returnStdout: true,
                script: "git log -n 1 --pretty=format:'%B'"
            ).trim()

            println "Current branch is ${branch}, Commit ID is ${env.TAG}, Image TAG is ${env.TAG}"
            // new Notification().getObject(env.JOB_NAME, "dingTalk", "").notification("success")
            isSuccess = true
        } catch (Exception e) {
            throw e
        }
    }

    if (env.gitlabBranch != null) {
        tasks["Pulling Code by trigger"] = {
            try {
                git(
                    url: env.GIT_URL,  // 使用 env.GIT_URL 获取 Jenkins Git 地址
                    branch: env.gitlabBranch,
                    changelog: true,
                    poll: true,
                    credentialsId: credentialsId
                )
                env.TAG = sh(
                    returnStdout: true,
                    script: "git log -n 1 --pretty=format:'%h'"
                ).trim()

                env.commitMessage = sh(
                    returnStdout: true,
                    script: "git log -n 1 --pretty=format:'%B'"
                ).trim()

                println "Current branch is ${env.gitlabBranch}, Commit ID is ${env.TAG}, Image TAG is ${env.TAG}"

                // new Notification().getObject(env.JOB_NAME, "dingTalk","").notification("success")
                isSuccess = true
            } catch (Exception e) {
                errMsg = e.toString()
                throw e
            }
        }
    }

    parallel tasks

    def stage = env.STAGE_NAME + '-pullCode'
    if (isSuccess) {
        updateGitlabCommitStatus(name: "${stage}", state: 'success')
        this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} OK...  \u221A")
    } else {
        updateGitlabCommitStatus(name: "${stage}", state: 'failed')
        this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} Failed...x @all")
        // throw exception，aborted pipeline
        error errMsg
    }
}



def dockerBuildPush(String harborAccount, String harborAdder) {

    def isSuccess = false
    def errMsg = ""
    container(name: 'docker') {
        try {
            withCredentials([usernamePassword(credentialsId: harborAccount, usernameVariable: 'HARBOR_USER_USR', passwordVariable: 'HARBOR_USER_PSW')]) {
                sh """ 
                    echo $HARBOR_USER_USR $HARBOR_USER_PSW $TAG 
                    docker build -t $harborAdder/$IMAGE_NAME:$TAG . 
                    docker login -u $HARBOR_USER_USR -p $HARBOR_USER_PSW $harborAdder  > /dev/null 2>&1
                    docker push $harborAdder/$IMAGE_NAME:$TAG 
                """
                isSuccess = true
            }
        } catch (Exception e) {
            errMsg = e.toString()
            throw e
        }

    this.msg = new BuildMessage()


                // check if build success
     def stage = env.STAGE_NAME + '-buildImages'
        if(isSuccess){
            updateGitlabCommitStatus(name: "${stage}", state: 'success')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} OK...  \u221A")
        }else {
            updateGitlabCommitStatus(name: "${stage}", state: 'failed')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} Failed...  x @all")
            // throw exception，aborted pipeline
            error errMsg
        }

    }
}





def buildCode(String language) {

    def isSuccess = false
    def errMsg = ""
    try {
        container(name: 'build') {
            switch (language) {
                case 'java':
                    sh """
                        #curl repo.maven.apache.org 
                        mvn clean install -DskipTests 
                        ls target/* 
                    """
                    break
                case 'npm':
                    sh """
                        npm config get cache                   
                        npm install --registry=https://registry.npm.taobao.org
                        npm run build
                    """
                    break
                case 'go':
                    sh """
                        export GO111MODULE=on
                        go env -w GOPROXY=https://goproxy.cn,direct
                        go get github.com/prometheus/client_golang/prometheus@v1.7.0
                        go env
                        go build
                    """
                    break
                default:
                    println "Unsupported language: ${language}"
                    break
            }
        }
            
        isSuccess = true
    } catch (Exception e) {
        errMsg = e.toString()
        throw e
    }

    this.msg = new BuildMessage()

     def stage = env.STAGE_NAME + '-buildCode'
    if(isSuccess){
            updateGitlabCommitStatus(name: "${stage}", state: 'success')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} OK...  \u221A")
    }else {
            updateGitlabCommitStatus(name: "${stage}", state: 'failed')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} Failed...  x @all")
            // throw exception，aborted pipeline
            error errMsg
    }
}






def deployToK8s(String credentialsId,String namespace) {
    isSuccess = false
    def errMsg = ""
    container(name: 'kubectl') {
        kubeconfig(credentialsId: credentialsId) {
            try {
                sh """
                    #/usr/local/bin/kubectl --kubeconfig $KUBECONFIG set image deploy -l app=${IMAGE_NAME} ${IMAGE_NAME}=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} -n $NAMESPACE
                    chmod 600 .*config
                    helm template deploy  \
                        --set deploy.name=${IMAGE_NAME} \
                        --set deploy.image.repository=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME} \
                        --set deploy.image.tag=${TAG} \
                        --set deploy.annotations.env=$NAMESPACE \
                        --set deploy.annotations.app=${IMAGE_NAME} \
                        --set deploy.namespace=$NAMESPACE \
                        | /usr/local/bin/kubectl --kubeconfig $KUBECONFIG apply -f -

                """


                sh """
                    timeout=180
                    start_time=\$(date +%s)
                    end_time=\$((start_time + timeout))
                    
                    while true; do
                        current_time=\$(date +%s)
                        
                        # 获取Deployment的状态
                        deployment_status=\$(kubectl get deployment "\$IMAGE_NAME" -n "\$NAMESPACE" -o jsonpath='{.status.conditions[?(@.type=="Available")].status}')
                        
                        if [ "\$deployment_status" = "True" ]; then
                            echo "Deployment is ready"
                            break
                        fi
                        
                        if [ "\$current_time" -ge "\$end_time" ]; then
                            echo "Timeout: Deployment is not ready within \$timeout seconds"
                            exit 1
                        fi
                        
                        sleep 5
                    done
                """

                isSuccess = true
            } catch (Exception e) {
                errMsg = e.toString()
                throw e
            }
        }
    }
    this.check = new Deploy()
    this.msg = new BuildMessage()
    def stage = env.STAGE_NAME + '-Deploy'
    if(isSuccess){
            updateGitlabCommitStatus(name: "${stage}", state: 'success')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} OK...  \u221A")
            

    }else {
            updateGitlabCommitStatus(name: "${stage}", state: 'failed')
            this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} Failed...  x@all")
            // throw exception，aborted pipeline
            error errMsg
    }

    // this.check.monitorDeployment(namespace, IMAGE_NAME)


}





import groovy.json.JsonBuilder
import java.net.URL
import java.nio.charset.StandardCharsets
import java.text.Normalizer


def sendDingTalkNotification(String title, String jobName, String branchName, String executionTime, String executor, String status, String commitMessage) {
    System.setProperty('LC_ALL', 'en_US.UTF-8')
    System.setProperty('LANG', 'en_US.UTF-8')



    def text

    if (title.contains("成功")) {
             text = """
                CI/CD\u4efb\u52a1\u6267\u884c \u001B[32m\u53D1\u5E03\u5B8C\u6210\u001B[0m \u901a\u77e5.
                \u4efb\u52a1ID: ${env.BUILD_ID}
                \u4efb\u52a1\u540d: ${jobName}
                \u9879\u76ee: ${env.JOB_NAME}
                \u5206\u652f: ${branchName}
                \u6267\u884c\u4eba: ${executor}
                \u8017\u65f6: ${executionTime}
                \u63d0\u4ea4\u4fe1\u606f: ${commitMessage}
            """
    }else if (title.contains("失败")) {
             text = """
                CI/CD\u4efb\u52a1\u6267\u884c \u001B[31m\u90E8\u7F72\u5931\u8D25\u001B[0m \u901a\u77e5.
                \u4efb\u52a1ID: ${env.BUILD_ID}
                \u4efb\u52a1\u540d: ${jobName}
                \u9879\u76ee: ${env.JOB_NAME}
                \u5206\u652f: ${branchName}
                \u6267\u884c\u4eba: ${executor}
                \u8017\u65f6: ${executionTime}
                \u63d0\u4ea4\u4fe1\u606f: ${commitMessage}
            """


    } else {
             text = """
                CI/CD\u4efb\u52a1\u6267\u884c \u001B[34m\u6B63\u5728\u90E8\u7F72\u001B[0m \u901a\u77e5.
                \u4efb\u52a1ID: ${env.BUILD_ID}
                \u4efb\u52a1\u540d: ${jobName}
                \u9879\u76ee: ${env.JOB_NAME}
                \u5206\u652f: ${branchName}
                \u6267\u884c\u4eba: ${executor}
                \u8017\u65f6: ${executionTime}
                \u63d0\u4ea4\u4fe1\u606f: ${commitMessage}
            """
    }



        // 对特殊字符进行转义
    def textEscaped = text.replaceAll("&", "&amp;")
                        .replaceAll("<", "&lt;")
                        .replaceAll(">", "&gt;")
                        .replaceAll("\"", "&quot;")
                        .replaceAll("'", "&#39;")

    def titleUTF8 = new String(title.getBytes("UTF-8"), "UTF-8")
    def textUTF8 = new String(textEscaped.getBytes("UTF-8"), "UTF-8")


    def url = "https://oapi.dingtalk.com/robot/send?access_token=f2a448c1c1450025ce95486dabfff9124c4cbf43789c81bec4913a37fd6e214d"
    def payload = [
        msgtype: "markdown",
        markdown: [
            title: titleUTF8,
            text: textUTF8,
            single_title: "查看详情",
            single_url: env.BUILD_URL
        ],
        at: [
            atMobiles: [],
            isAtAll: true
        ]
    ]
    def requestBody = new groovy.json.JsonBuilder(payload).toString()

    def connection = new URL(url).openConnection()
    connection.setRequestMethod("POST")
    connection.setRequestProperty("Content-Type", "application/json")
    connection.setDoOutput(true)

    try {
        def outputStream = connection.getOutputStream()
        outputStream.write(requestBody.getBytes("UTF-8"))
        outputStream.flush()
        outputStream.close()

        // Read response
        def responseCode = connection.getResponseCode()
        if (responseCode >= 200 && responseCode < 300) {
            println("Notification sent successfully")
        } else {
            println("Failed to send notification. Response code: ${responseCode}")
        }
    } finally {
        connection.disconnect()
    }
}

